package cn.lili.modules.goods.entity.dos;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.utils.StringUtils;
import cn.lili.modules.goods.entity.dto.GoodsOperationDTO;
import cn.lili.modules.goods.entity.enums.GoodsStatusEnum;
import cn.lili.modules.goods.entity.enums.GoodsTypeEnum;
import cn.lili.modules.goods.entity.vos.BatchGoodsImportVo;
import cn.lili.mybatis.BaseEntity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.xkcoding.http.util.StringUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.Map;

/**
 * 商品
 *
 * @author pikachu
 * @since 2020-02-23 9:14:33
 */
// @EqualsAndHashCode(callSuper = true)
// @Data
@TableName("li_goods")
@ApiModel(value = "商品")
@Data
public class Goods extends BaseEntity {

	private static final long serialVersionUID = 370683495251252601L;

	@ApiModelProperty(value = "商品名称")
	@NotEmpty(message = "商品名称不能为空")
	@Length(max = 100, message = "商品名称太长，不能超过100个字符")
	private String goodsName;

	@ApiModelProperty(value = "商品价格", required = true)
	@NotNull(message = "商品价格不能为空")
	@Min(value = 0, message = "商品价格不能为负数")
	@Max(value = 99999999, message = "商品价格不能超过99999999")
	private Double price;

	@ApiModelProperty(value = "品牌id")
	private String brandId;

	@ApiModelProperty(value = "分类path")
	private String categoryPath;

	@ApiModelProperty(value = "计量单位")
	private String goodsUnit;

	@Length(max = 60, message = "商品卖点太长，不能超过60个字符")
	@ApiModelProperty(value = "卖点")
	private String sellingPoint;

	/**
	 * @see GoodsStatusEnum
	 */
	@ApiModelProperty(value = "上架状态 UPPER上架，DOWN下架")
	private String marketEnable;

	@ApiModelProperty(value = "详情")
	private String intro;

	@ApiModelProperty(value = "购买数量")
	private Integer buyCount;

	@Max(value = 99999999, message = "库存不能超过99999999")
	@ApiModelProperty(value = "库存")
	private Integer quantity;

	@ApiModelProperty(value = "商品好评率")
	private Double grade;

	@ApiModelProperty(value = "缩略图路径")
	private String thumbnail;

	@ApiModelProperty(value = "小图路径")
	private String small;

	@ApiModelProperty(value = "原图路径")
	private String original;

	@ApiModelProperty(value = "店铺分类id")
	private String storeCategoryPath;

	@ApiModelProperty(value = "评论数量")
	private Integer commentNum;

	@ApiModelProperty(value = "卖家id")
	private String storeId;

	@ApiModelProperty(value = "卖家名字")
	private String storeName;

	@ApiModelProperty(value = "运费模板id")
	private String templateId;

	@ApiModelProperty(value = "审核状态")
	private String authFlag;

	@ApiModelProperty(value = "审核信息")
	private String authMessage;

	@ApiModelProperty(value = "下架原因")
	private String underMessage;

	@ApiModelProperty(value = "是否自营")
	private Boolean selfOperated;

	@ApiModelProperty(value = "商品移动端详情")
	private String mobileIntro;

	@ApiModelProperty(value = "商品视频")
	private String goodsVideo;

	@ApiModelProperty(value = "是否为推荐商品", required = true)
	private Boolean recommend;

	@ApiModelProperty(value = "推荐排名", required = true)
	private int recommendRanking;

	@ApiModelProperty(value = "销售模式", required = true)
	private String salesModel;

	/**
	 * @see cn.lili.modules.goods.entity.enums.GoodsTypeEnum
	 */
	@ApiModelProperty(value = "商品类型", required = true)
	private String goodsType;

	@ApiModelProperty(value = "商品参数json", hidden = true)
	@JsonIgnore
	private String params;

	@ApiModelProperty(value = "地址id，'，'分割 ")
	private String storeAddressIdPath;

	@ApiModelProperty(value = "地址名称， '，'分割")
	private String storeAddressPath;

	@ApiModelProperty(value = "排序 数字越大越前")
	private Long sort;

	@ApiModelProperty(value = "保质期")
	private String shelfLife;

	@ApiModelProperty(value = "生产日期")
	private String productionDate;

	@ApiModelProperty(value = "店铺内排序")
	private int num;

	@ApiModelProperty(value = "高德坐标系经度")
	private String lon;

	@ApiModelProperty(value = "高德坐标系纬度")
	private String lat;

	@ApiModelProperty(value = "地址名称")
	private String addressPath;

	@ApiModelProperty(value = "行政区划代码")
	private String adressCode;

	@ApiModelProperty(value = "0是全国销售  1是区域销售")
	private String salesArea;

	@ApiModelProperty(value = "来源（pc   app）")
	private String origin = "pc";

	public Goods() {
	}

	public Goods(GoodsOperationDTO goodsOperationDTO) {
		this.goodsName = goodsOperationDTO.getGoodsName();
		this.categoryPath = goodsOperationDTO.getCategoryPath();
		this.storeCategoryPath = goodsOperationDTO.getStoreCategoryPath();
		this.brandId = goodsOperationDTO.getBrandId();
		this.templateId = goodsOperationDTO.getTemplateId();
		this.recommend = goodsOperationDTO.getRecommend();
		this.sellingPoint = goodsOperationDTO.getSellingPoint();
		this.salesModel = goodsOperationDTO.getSalesModel();
		this.goodsUnit = goodsOperationDTO.getGoodsUnit();
		this.intro = goodsOperationDTO.getIntro();
		this.mobileIntro = goodsOperationDTO.getMobileIntro();
		this.goodsVideo = goodsOperationDTO.getGoodsVideo();
		this.price = goodsOperationDTO.getPrice();
		this.storeAddressPath = goodsOperationDTO.getRegion();
		this.addressPath = goodsOperationDTO.getRegion();
		this.storeAddressIdPath = goodsOperationDTO.getRegionId();
		this.salesArea = goodsOperationDTO.getSalesArea();
		this.shelfLife = goodsOperationDTO.getShelfLife();
		this.num = goodsOperationDTO.getNum();
		this.productionDate = goodsOperationDTO.getProductionDate();
		if (goodsOperationDTO.getGoodsParamsDTOList() != null && goodsOperationDTO.getGoodsParamsDTOList().isEmpty()) {
			this.params = JSONUtil.toJsonStr(goodsOperationDTO.getGoodsParamsDTOList());
		}
		// 如果立即上架则
		this.marketEnable = Boolean.TRUE.equals(goodsOperationDTO.getRelease())
				? GoodsStatusEnum.UPPER.name()
				: GoodsStatusEnum.DOWN.name();
		this.goodsType = goodsOperationDTO.getGoodsType();
		this.grade = 100D;
		this.origin = goodsOperationDTO.getOrigin();

		// 循环sku，判定sku是否有效
		for (Map<String, Object> sku : goodsOperationDTO.getSkuList()) {
			// 判定参数不能为空
			if (!sku.containsKey("sn") || sku.get("sn") == null) {
				throw new ServiceException(ResultCode.GOODS_SKU_SN_ERROR);
			}
			if (!sku.containsKey("price") || StringUtil.isEmpty(sku.get("price").toString())
					|| Convert.toDouble(sku.get("price")) <= 0) {
				throw new ServiceException(ResultCode.GOODS_SKU_PRICE_ERROR);
			}
			if (!sku.containsKey("cost") || StringUtil.isEmpty(sku.get("cost").toString())
					|| Convert.toDouble(sku.get("cost")) <= 0) {
				throw new ServiceException(ResultCode.GOODS_SKU_COST_ERROR);
			}
			// 虚拟商品没有重量字段
			// if (this.goodsType.equals(GoodsTypeEnum.PHYSICAL_GOODS.name()) &&
			// (!sku.containsKey("weight") ||
			// sku.containsKey("weight") &&
			// (StringUtil.isEmpty(sku.get("weight").toString()) ||
			// Convert.toDouble(sku.get("weight").toString()) < 0))) {
			// throw new ServiceException(ResultCode.GOODS_SKU_WEIGHT_ERROR);
			// }
			if (!sku.containsKey("quantity") || StringUtil.isEmpty(sku.get("quantity").toString())
					|| Convert.toInt(sku.get("quantity").toString()) < 0) {
				throw new ServiceException(ResultCode.GOODS_SKU_QUANTITY_ERROR);
			}

		}
	}

	public Goods(BatchGoodsImportVo batchGoodsImportVo) {
		this.goodsName = batchGoodsImportVo.getGoodsName();
		this.categoryPath = batchGoodsImportVo.getCategoryPath();
		this.storeCategoryPath = batchGoodsImportVo.getStoreCategoryPath();
		this.brandId = batchGoodsImportVo.getBrandId();
		this.templateId = batchGoodsImportVo.getTemplateId();
		this.recommend = batchGoodsImportVo.getRecommend();
		this.recommendRanking = batchGoodsImportVo.getRecommendRanking();
		this.sellingPoint = batchGoodsImportVo.getSellingPoint();
		this.salesModel = batchGoodsImportVo.getSalesModel();
		this.goodsUnit = batchGoodsImportVo.getGoodsUnit();
		this.intro = batchGoodsImportVo.getIntro();
		this.mobileIntro = batchGoodsImportVo.getMobileIntro();
		if (StringUtils.isNotBlank(batchGoodsImportVo.getPrice())) {
			this.price = Double.parseDouble(batchGoodsImportVo.getPrice().trim());
		} else {
			this.price = 0.0;
		}
		this.marketEnable = Boolean.TRUE.equals(batchGoodsImportVo.getRelease())
				? GoodsStatusEnum.UPPER.name()
				: GoodsStatusEnum.DOWN.name();
		this.goodsType = batchGoodsImportVo.getGoodsType();
		this.grade = 100D;
		this.shelfLife = batchGoodsImportVo.getShelfLife();
		this.productionDate = batchGoodsImportVo.getProductionDate();
		this.num = batchGoodsImportVo.getNum();
		this.origin = batchGoodsImportVo.getOrigin();

	}

	public String getIntro() {
		if (CharSequenceUtil.isNotEmpty(intro)) {
			return HtmlUtil.unescape(intro);
		}
		return intro;
	}

	public String getMobileIntro() {
		if (CharSequenceUtil.isNotEmpty(mobileIntro)) {
			return HtmlUtil.unescape(mobileIntro);
		}
		return mobileIntro;
	}

	public String getGoodsName() {
		return goodsName;
	}

	public void setGoodsName(String goodsName) {
		this.goodsName = goodsName;
	}

	public Double getPrice() {
		return price;
	}

	public void setPrice(Double price) {
		this.price = price;
	}

	public String getBrandId() {
		return brandId;
	}

	public void setBrandId(String brandId) {
		this.brandId = brandId;
	}

	public String getCategoryPath() {
		return categoryPath;
	}

	public void setCategoryPath(String categoryPath) {
		this.categoryPath = categoryPath;
	}

	public String getGoodsUnit() {
		return goodsUnit;
	}

	public void setGoodsUnit(String goodsUnit) {
		this.goodsUnit = goodsUnit;
	}

	public String getSellingPoint() {
		return sellingPoint;
	}

	public void setSellingPoint(String sellingPoint) {
		this.sellingPoint = sellingPoint;
	}

	public String getMarketEnable() {
		return marketEnable;
	}

	public String getStoreAddressIdPath() {
		return storeAddressIdPath;
	}

	public void setStoreAddressIdPath(String storeAddressIdPath) {
		this.storeAddressIdPath = storeAddressIdPath;
	}

	public void setMarketEnable(String marketEnable) {
		this.marketEnable = marketEnable;
	}

	public void setIntro(String intro) {
		this.intro = intro;
	}

	public Integer getBuyCount() {
		return buyCount;
	}

	public void setBuyCount(Integer buyCount) {
		this.buyCount = buyCount;
	}

	public Integer getQuantity() {
		return quantity;
	}

	public void setQuantity(Integer quantity) {
		this.quantity = quantity;
	}

	public Double getGrade() {
		return grade;
	}

	public void setGrade(Double grade) {
		this.grade = grade;
	}

	public String getThumbnail() {
		if (StringUtils.isNotBlank(thumbnail) && thumbnail.lastIndexOf("?") > 0) {
			thumbnail = thumbnail.substring(0, thumbnail.lastIndexOf("?"));
		}
		return thumbnail;
	}

	public void setThumbnail(String thumbnail) {
		this.thumbnail = thumbnail;
	}

	public String getSmall() {
		if (StringUtils.isNotBlank(small)) {
			if (small.lastIndexOf("?") > 0) {
				small = small.substring(0, small.lastIndexOf("?"));
			}
		}
		return small;
	}

	public void setSmall(String small) {
		this.small = small;
	}

	public String getOriginal() {
		return original;
	}

	public void setOriginal(String original) {
		this.original = original;
	}

	public String getStoreCategoryPath() {
		return storeCategoryPath;
	}

	public void setStoreCategoryPath(String storeCategoryPath) {
		this.storeCategoryPath = storeCategoryPath;
	}

	public Integer getCommentNum() {
		return commentNum;
	}

	public void setCommentNum(Integer commentNum) {
		this.commentNum = commentNum;
	}

	public String getStoreId() {
		return storeId;
	}

	public void setStoreId(String storeId) {
		this.storeId = storeId;
	}

	public String getStoreName() {
		return storeName;
	}

	public void setStoreName(String storeName) {
		this.storeName = storeName;
	}

	public String getTemplateId() {
		return templateId;
	}

	public void setTemplateId(String templateId) {
		this.templateId = templateId;
	}

	public String getAuthFlag() {
		return authFlag;
	}

	public void setAuthFlag(String authFlag) {
		this.authFlag = authFlag;
	}

	public String getAuthMessage() {
		return authMessage;
	}

	public void setAuthMessage(String authMessage) {
		this.authMessage = authMessage;
	}

	public String getUnderMessage() {
		return underMessage;
	}

	public void setUnderMessage(String underMessage) {
		this.underMessage = underMessage;
	}

	public Boolean getSelfOperated() {
		return selfOperated;
	}

	public void setSelfOperated(Boolean selfOperated) {
		this.selfOperated = selfOperated;
	}

	public void setMobileIntro(String mobileIntro) {
		this.mobileIntro = mobileIntro;
	}

	public String getGoodsVideo() {
		return goodsVideo;
	}

	public void setGoodsVideo(String goodsVideo) {
		this.goodsVideo = goodsVideo;
	}

	public Boolean getRecommend() {
		return recommend;
	}

	public void setRecommend(Boolean recommend) {
		this.recommend = recommend;
	}

	public int getRecommendRanking() {
		return recommendRanking;
	}

	public void setRecommendRanking(int recommendRanking) {
		this.recommendRanking = recommendRanking;
	}

	public String getSalesModel() {
		return salesModel;
	}

	public void setSalesModel(String salesModel) {
		this.salesModel = salesModel;
	}

	public String getGoodsType() {
		return goodsType;
	}

	public void setGoodsType(String goodsType) {
		this.goodsType = goodsType;
	}

	public String getParams() {
		return params;
	}

	public void setParams(String params) {
		this.params = params;
	}

	public String getStoreAddressPath() {
		return storeAddressPath;
	}

	public void setStoreAddressPath(String storeAddressPath) {
		this.storeAddressPath = storeAddressPath;
	}

	public Long getSort() {
		return sort;
	}

	public void setSort(Long sort) {
		this.sort = sort;
	}

	public String getShelfLife() {
		return shelfLife;
	}

	public void setShelfLife(String shelfLife) {
		this.shelfLife = shelfLife;
	}

	public String getProductionDate() {
		return productionDate;
	}

	public void setProductionDate(String productionDate) {
		this.productionDate = productionDate;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getLon() {
		return lon;
	}

	public void setLon(String lon) {
		this.lon = lon;
	}

	public String getLat() {
		return lat;
	}

	public void setLat(String lat) {
		this.lat = lat;
	}

	public String getAddressPath() {
		return addressPath;
	}

	public void setAddressPath(String addressPath) {
		this.addressPath = addressPath;
	}

	public String getAdressCode() {
		return adressCode;
	}

	public void setAdressCode(String adressCode) {
		this.adressCode = adressCode;
	}

	public String getSalesArea() {
		return salesArea;
	}

	public void setSalesArea(String salesArea) {
		this.salesArea = salesArea;
	}

	public String getOrigin() {
		return origin;
	}

	public void setOrigin(String origin) {
		this.origin = origin;
	}
}